%%{
  machine esi_common_parser;

  # inline tags e.g. <esi:comment text='some useless text'/> or <esi:include src='/foo/'/>, etc...
  esi_inline_tag = (
    start: (
      '<esi:' [a-z]+ space @see_start_tag -> start_attribute |
      '<esi:' [a-z]+ space* '/>' >see_start_tag %see_end_tag -> final
    ),
    start_attribute: (
      space* [a-zA-Z_\-]+ [a-zA-Z_\-0-9]* '=' @see_attribute_key -> end_attribute | '/>' @see_end_tag -> final
    ),
    end_attribute: (
      space* ['"][!{}#-&(-/:-@a-zA-Z0-9+_\-]+['"] @see_attribute_value -> start_attribute
    )
  ) >begin %finish;

  # block tags e.g. <esi:try>  <esi:attempt>, etc..
  esi_block_tag = (
    start: (
      '<esi:' [a-z]+ '>' @block_start_tag -> start |
      '<esi:' [a-z]+ space @see_start_tag -> start_attribute |
      '</esi:' [a-z]+ '>' @block_end_tag
    ),
    start_attribute: (
      space* [a-zA-Z_\-]+ [a-zA-Z_\-0-9]* '=' @see_attribute_key -> end_attribute | '>' @see_block_start_with_attributes -> final
    ),
    end_attribute: (
      space* ['"][!{}#-&(-/:-@a-zA-Z0-9+_\-]+['"] @see_attribute_value -> start_attribute
    )
  ) >begin  %finish;

  echo_state = (
    start: (
      /./ @echo
    )
  );

#  tag_end = '/>';
#  tag_start_expr = '<esi:' @start_reading_tag_name;
#  read_tag := word+ any-space+ @end_reading_tag_name ;
  main := ((/.*/)? @echo (esi_inline_tag|esi_block_tag) )*;
}%%
